Log Rotation
Access log rotation is the process of:
- Periodically archiving current access logs
- Creating new log files
- Optionally compressing or deleting old logs
This prevents:
- Disk space exhaustion
- Performance degradation
- Unmanageable log files
- Compliance violations
NGINX does NOT rotate logs automatically — rotation must be handled externally.
Why Log Rotation Is Critical (Security & Monitoring)
| Risk Without Rotation | Impact |
|---|---|
| Disk fills up | NGINX crashes |
| Huge log files | Slow analysis |
| No retention | Compliance issues |
| No compression | Wasted storage |
How NGINX Handles Access Logs Internally
- NGINX keeps file descriptors open
- Renaming a log file does not stop logging
- NGINX must be reloaded or signaled to reopen logs
This is why rotation requires reload or USR1 signal.
Recommended Tool: logrotate
On most Linux systems, logrotate is the standard and safest solution.
Basic Access Log Rotation Configuration
Example: Rotate NGINX Access Logs Daily
/var/log/nginx/access.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 nginx adm
sharedscripts
postrotate
systemctl reload nginx > /dev/null 2>&1
endscript
}
Explanation of Each Directive
| Directive | Meaning |
|---|---|
daily | Rotate every day |
rotate 14 | Keep 14 old logs |
compress | Gzip old logs |
delaycompress | Compress from 2nd rotation |
missingok | Don’t error if log missing |
notifempty | Skip empty logs |
create | Create new file with permissions |
sharedscripts | Run postrotate once |
postrotate | Reload NGINX to reopen logs |
How Rotation Actually Works (Step-by-Step)
access.log→ renamed toaccess.log.1- Older logs shift:
.2,.3, etc. - New empty
access.logis created - NGINX reloads and writes to new file
- Old logs optionally compressed
Rotating Multiple Access Logs
If you use per-site access logs:
/var/log/nginx/\*access.log {
daily
rotate 7
compress
missingok
notifempty
sharedscripts
postrotate
systemctl reload nginx > /dev/null 2>&1
endscript
}
Rotation with Custom Access Log Formats
Example NGINX config:
log_format security '$remote_addr [$time_iso8601] "$request" $status';
access_log /var/log/nginx/security_access.log security;
Logrotate:
/var/log/nginx/security_access.log {
daily
rotate 30
compress
create 0640 nginx adm
postrotate
systemctl reload nginx
endscript
}
Log rotation is independent of log format.
Using USR1 Signal Instead of Reload (Advanced)
postrotate
kill -USR1 `cat /run/nginx.pid`
endscript
- Faster than reload
- No config revalidation
- Preferred for high-traffic systems
Log Rotation in Containers (Docker / Kubernetes)
Best Practice
access_log /dev/stdout;
error_log /dev/stderr;
- Let container runtime handle rotation
- Avoids file-based logs
Security Considerations for Log Rotation
| Practice | Benefit |
|---|---|
| Limited permissions | Prevent log tampering |
| Compression | Protects storage |
| Retention policy | Compliance |
| Central shipping | Incident response |
| Immutable storage | Forensics |
Common Log Rotation Mistakes
| Mistake | Impact |
|---|---|
| No reload/USR1 | Logs continue writing to old file |
| No compression | Disk usage spikes |
| Too long retention | Storage waste |
| Too short retention | Loss of evidence |
| World-readable logs | Information leak |
- Recommended Production Setup NGINX
access_log /var/log/nginx/access.log main;
Logrotate
/var/log/nginx/access.log {
daily
rotate 14
compress
delaycompress
create 0640 nginx adm
postrotate
kill -USR1 `cat /run/nginx.pid`
endscript
}